home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 422_04 / monitor.asm < prev    next >
Encoding:
Assembly Source File  |  1994-02-14  |  19.1 KB  |  646 lines

  1.     TITLE    8080/8085 SYSTEM MONITOR
  2. ****************************************************************
  3. *                   8080/8085 SYSTEM MONITOR                   *
  4. *--------------------------------------------------------------*
  5. *  COMMANDS:                                                   *
  6. *    B .................... ENTER RESIDENT BASIC INTERPRETER.  *
  7. *    D .................... DOWNLOAD FROM TERMINAL PORT.       *
  8. *    G <ADR> .............. GO (EXECUTE) AT ADDRESS.           *
  9. *    L .................... LOAD MEMORY FROM TAPE.             *
  10. *    M <ADR>,<ADR> ........ DISPLAY MEMORY IN HEXIDECIMAL.     *
  11. *    R .................... REENTER RESIDENT BASIC.            *
  12. *    S <ADR> [NN]-<BYT> ... SUBSTUTE INTO MEMORY.              *
  13. *    T 'H' OR 'F' ......... TERMINAL EMULATION MODE.           *
  14. *    U <WRD> .............. REINITIALIZE 8251 UART.            *
  15. *    W <ADDR>,<ADDR> ...... WRITE MEMORY TO TAPE.              *
  16. ****************************************************************
  17.     PAGE
  18. *
  19. * CONSTANTS AND EQUATES...
  20. *
  21. DEFIO    EQU    3        DEFAULT I/O CONFIGURATION
  22. KEYBRD    EQU    0        KEYBOARD INPUT PORT
  23. UCTL    EQU    2        UART CONTROL/STATUS PORT
  24. UDAT    EQU    1        UART DATA PORT
  25. VIDEO    EQU    $1000        VIDEO DISPLAY RAM ADDRESS
  26. BUFF    EQU    $1400        INPUT BUFFER
  27. IOCON    EQU    BUFF+$FF    I/O CONFIGURATION
  28. USROUT    EQU    IOCON-2        USER OUTPUT ROUTINE VECTOR
  29. CURSOR    EQU    USROUT-2    CURRENT CURSOR POSITION
  30. LSTCHR    EQU    CURSOR-1    CHARACTER UNDER CURSOR
  31. STACK    EQU    LSTCHR        SYSTEM STACK
  32. BASIC    EQU    $400        ADDRESS OF RESIDENT BASIC INTERPRETER
  33. RENTRY    EQU    BASIC+$A3    ADDRESS TO REENTER BASIC
  34.     PAGE
  35. *
  36. * START OF MONITOR, FIRST INITIALIZE THE HARDWARE
  37. *
  38. START    LXI    SP,STACK    INITALIZE STACK
  39.     LXI    H,0        SET USRIO TO ZERO...
  40.     SHLD    USROUT        TO INDICATE IT HASN'T BEEN SET
  41.     MVI    A,DEFIO        DEFAULT I/O CONFIGURATION
  42.     STA    IOCON        SET I/O CONFIGURATION
  43.     LXI    H,$7A37        USART 7 BITS, NO PARITY, HIGH-SPEED
  44.     CALL    SETURT        INITIALIZE 8251
  45.     MVI    A,$0C        CLEAR SCREEN CHARACTER
  46.     CALL    OUT        DISPLAY
  47.     JMP    PRNT        PROMPT FOR COMMAND
  48. * GETS DOUBLE VALUE FOR HL, DE
  49. DGET    CALL    AGET        GET FIRST ADDRESS
  50.     XCHG            SWAP
  51.     MVI    A,','        GET SEPERATOR CHARACTER
  52.     CALL    OUT        DISPLAY
  53. * GETS TWO BYTE VALUE FOR H-L
  54. AGET    CALL    GETHL        GET HEX VALUE
  55.     RC            RETURN IF OK
  56. * INDICATE ERROR WITH '?' ON CONSOLE
  57. ERROR    MVI    A,'?'        ERROR MESSAGE
  58.     CALL    OUT        DISPLAY IT
  59. * RECOVER FROM ERROR, RESET STACK, SHUT TAPE OFF
  60. ABORT    LXI    SP,STACK    FIX UP STACK
  61.     CALL    TOFF        SHUT OFF TAPE
  62.     CALL    NL        NEW LINE ON TERMINAL
  63. * WAIT FOR COMMAND
  64. PRNT    MVI    A,'*'        PROMPT MESSAGE
  65.     CALL    OUT        DISPLAY
  66.     CALL    IN        GET CHARACTER FROM TERMINAL
  67.     CALL    OUT        ECHO
  68.     MOV    B,A        SAVE FOR COMPARISON
  69.     CALL    SPACE        DISPLAY SEPARATER
  70.     LXI    H,CTAB        POINT TO COMMAND TABLE
  71. CLOOK    MOV    A,M        GET CMD FROM TABLE
  72.     INX    H        POINT TO NEXT
  73.     ANA    A        TEST FOR END IF TABLE
  74.     JZ    ERROR        IF SO, INDICATE SO
  75.     MOV    E,M        GET LOW ADDRESS
  76.     INX    H        POINT TO HIGH
  77.     MOV    D,M        GET HIGH ADDRESS
  78.     INX    H        POINT TO NEXT
  79.     CMP    B        TEST FOR ENTERED COMMAND
  80.     JNZ    CLOOK        KEEP LOOKING TILL WE FIND
  81.     LXI    H,ABORT        ADDRESS TO RETURN TO
  82.     PUSH    H        SAVE RETURN ADDRESS
  83.     XCHG            SWAP TO H-L
  84.     PCHL            EXECUTE USER CODE
  85. CTAB    DB    'B'        BASIC COMMAND?
  86.     DW    BASIC        ADDRESS OF BASIC INTERPRETER
  87.     DB    'R'        TEST FOR 'REENTER'
  88.     DW    RENTRY        REENTER BASIC
  89.     DB    'D'        TEST FOR DOWNLOAD
  90.     DW    DNLD        PERFORM DOWNLOAD
  91.     DB    'L'        TEST FOR 'LOAD'
  92.     DW    LOAD        LOAD FROM TAPE
  93.     DB    'U'        TEST FOR 'UART'
  94.     DW    UART        SET UP UART
  95.     DB    'G'        TEST FOR 'GO'
  96.     DW    GO        GO EXECUTE
  97.     DB    'S'        TEST FOR 'SUB'
  98.     DW    SUBST        SUBST. MEMORY
  99.     DB    'W'        TEST FOR 'WRITE'
  100.     DW    DUMP        DUMP SOME OUT
  101.     DB    'M'        TEST FOR 'M'
  102.     DW    MEMRY        MEMORY CODE
  103.     DB    'T'        TERMINAL MODE???
  104.     DW    TMODE        IF SO, ENTER TERMINAL
  105.     DB    0        INDICATE END OF TABLE
  106. *
  107. * DISPLAY MEMORY COMMAND
  108. *
  109. MEMRY    CALL    DGET        GET ADDRESSES
  110.     XCHG            SWAP BACK
  111. MLOOP    CALL    NL        START A NEW LINE
  112.     CALL    HLOUT        DISPLAY ADDRESS
  113. ML1    CALL    SPACE        DISPLAY SPACE
  114.     MOV    A,M        GET CONTENTS
  115.     CALL    HOUT        DISPLAY HEX
  116.     CALL    CHLDE        TEST FOR END
  117.     RNC            IF SO, STOP
  118.     INX    H        NEXT BYTE
  119.     MOV    A,L        GET LOW ADDRESS
  120.     ANI    $0F        TEST FOR END OF LINE
  121.     JNZ    ML1        IF NOT, KEEP GOING
  122.     CALL    CTRLC        TEST FOR USER ABORT
  123.     JNZ    MLOOP        IF NOT, KEEP DISPLAYING
  124.     RET
  125. *
  126. * GO COMMAND
  127. *
  128. GO    CALL    AGET        GET ADDRESS TO 'GO' AT
  129.     PCHL            SET PROGRAM COUNTER
  130. *
  131. * SUBSTUTUTE COMMAND
  132. *
  133. SUBST    CALL    AGET        GET ADDRESS
  134. SUB0    CALL    NL        START ON A NEW LINE
  135.     CALL    HLOUT        DISPLAY ADDRESS
  136.     MVI    D,8        EIGHT BYTES/LINE
  137. SUB1    CALL    SPACE        SKIP A SPACE
  138.     MOV    A,M        GET CONTENTS
  139.     CALL    HOUT        DISPLAY
  140.     MVI    A,'-'        PROMPT WITH '-'
  141.     CALL    OUT        DISPLAY
  142.     CALL    GETBYT        GET BYTE
  143.     JC    SUB3        IF OK, SUBSTUTE
  144.     CPI    $0D        TEST FOR ABORT
  145.     RZ            IF SO, BACK FOR COMMAND
  146.     CALL    SPACE        OTHERWISE, PRINT.
  147.     CALL    SPACE        TWO SPACES (SAME SPACE AS HEX DIGITS)
  148.     MOV    A,M        GET OLD BYTE BACK
  149. SUB3    MOV    M,A        REPLACE MEMORY CONTENTS
  150. SNXT    INX    H        NEXT LOCATION IN MEMORY
  151.     DCR    D        REDUCE COUNT OF BYTES/LINE
  152.     JNZ    SUB1        IF OK, STAY ON SAME LINE
  153.     JMP    SUB0        OTHERWISE GO TO NEW LINE
  154. *
  155. * DUMP COMMAND
  156. *
  157. DUMP    CALL    DGET        GET ADDRESSES
  158. * DE=START ADDRESS, H-L=END ADDRESS
  159. DUMP1    INX    H        ADVANCE BY ONE BYTE
  160.     MOV    A,H        TEST FOR SPECIAL CASE
  161.     ANA    A        IF ZERO PAGE
  162.     JZ    LBOT        IF SO, SPECIAL CASE
  163.     PUSH    H        SAVE ENDING VALUE
  164.     LXI    B,$FF01        GET VALUE TO SUBTRACT
  165.     DAD    B        SUBTRACT FROM ENDING ADDRESS
  166.     XCHG            SWAP BACK
  167.     CALL    TON        START TAPE DRIVE
  168. DRECL    CALL    CHLDE        SEE IF WE HAVE FINISHED YET
  169.     JNC    LREC        IF SO, LAST RECORD
  170.     MVI    A,$FF        OTHERWISE, RECORD LENGTH IS 255
  171.     CALL    DUMPR        DUMP OUT RECORD
  172.     JMP    DRECL        KEEP GOING TILL LAST RECORD
  173. LREC    POP    D        GET ADDRES BACK
  174.     XCHG            SWAP
  175. LBOT    PUSH    D        GET ADDRESS BACK
  176.     MOV    A,D        TAKE.
  177.     CMA            TWO'S.
  178.     MOV    D,A        COMPLEMENT.
  179.     MOV    A,E        SO WE CAN.
  180.     CMA            SUBTRACT.
  181.     MOV    E,A        FROM THE
  182.     INX    D        ORIGIONAL ADDRESS
  183.     DAD    D        SUBTRACT
  184.     MOV    A,L        GET LENGTH
  185.     POP    H        GET ADDRESS BACK
  186.     CALL    DUMPR        DUMP LAST RECORD
  187.     SUB    A        END OF FILE INDICATOR
  188. *
  189. * DUMPS A RECORD IN INTEL HEX FORMAT
  190. *
  191. DUMPR    MOV    B,A        SAVE LENGTH IN B
  192.     MVI    A,4        SET FOR UART OUTPUT
  193.     STA    IOCON        SET I/O CONF
  194.     CALL    NL        DISPLAY LF CR TO TAPE
  195.     MVI    A,':'        START OF RECORD
  196.     CALL    OUT        WRITE TO TABE
  197.     MOV    A,B        GET LENGTH
  198.     MOV    C,A        START CHECKSUM
  199.     CALL    HOUT        WRITE LENGTH TO TAPE
  200.     MOV    A,B        GET LENGTH BACK
  201.     ANA    A        TEST FOR END OF FILE
  202.     JZ    ENDMP        IF SO, STOP
  203.     CALL    HLOUT        WRITE ADDRESS TO TAPE
  204.     MOV    A,C        GET CHECKSUM
  205.     ADD    H        ADD HIGH ADDRESS
  206.     ADD    L        ADD LOW ADDRESS
  207.     MOV    C,A        RESAVE CHECKSUM
  208.     SUB    A        DATA TYPE ZERO
  209.     CALL    HOUT        WRITE TO TAPE
  210. MHEX    MOV    A,M        GET BYTE OF DATA TO DUMP
  211.     CALL    HOUT        WRITE TO TAPE
  212.     MOV    A,M        GET DATA BACK
  213.     ADD    C        ADD TO CHECKSUM
  214.     MOV    C,A        RESAVE CHECKSUM
  215.     INX    H        NEXT MEMORY LOCATION
  216.     DCR    B        REDUCE LENGTH
  217.     JNZ    MHEX        IF NOT END, KEEP DUMPING
  218.     CMA            INVERT TO MAKE.
  219.     INR    A        TWO'S COMPLEMENT CHECKSUM
  220.     CALL    HOUT        WRITE CHECKSUM TO TAPE
  221. ENDMP    MVI    A,DEFIO        GET DEFAULT I/O CONF
  222.     STA    IOCON        RESET I/O CONFIGURATION
  223.     RET
  224. *
  225. * COMPARE'S H-L WITH D-E
  226. *
  227. CHLDE    MOV    A,H        GET HIGH IF HL
  228.     CMP    D        TEST WITH HIGH OF DE
  229.     RNZ            IF NOT SAME, PROBLEM SOLVED
  230.     MOV    A,L        GET LOW HL
  231.     CMP    E        SET FLAGS FOR COMPARE WITH LOW DE
  232.     RET
  233. * DISPLAYS A SPACE ON THE TERMINAL
  234. SPACE    MVI    A,' '        GET A SPACE
  235.     JMP    OUT        DISPLAY
  236. *
  237. * DISPLAYS 16 BIT VALUE OF H-L ON THE TERMINAL
  238. *
  239. HLOUT    MOV    A,H        GET H
  240.     CALL    HOUT        DISPLAY H IN HEX
  241.     MOV    A,L        GET L
  242. * DISPLYS 8 BIT VALUE OF ACC IN HEX
  243. HOUT    PUSH    PSW        SAVE LOW DIGIT
  244.     RRC            MAKE HIGH.
  245.     RRC            DIGIT.
  246.     RRC            INTO.
  247.     RRC            LOW DIGIT.
  248.     CALL    HXOUT        PRINT HIGH DIGIT
  249.     POP    PSW        GET LOW DIGIT BACK
  250. HXOUT    ANI    $0F        GET RID OF EXCESS BAGGAGE
  251.     ADI    $30        CONVERT TO ASCII NUMBER
  252.     CPI    $3A        TEST FOR ALPHA CHARACTER
  253.     JC    OUT        IF NOT, WE ARE OK
  254.     ADI    7        CONVERT TO CHARACTER
  255. *
  256. * OUTPUT ROUTINE, DISPLAYS CONTENTS OF ACC ON ALL ENABLED
  257. * OUTPUT DEVICES
  258. *
  259. OUT    PUSH    B        SAVE B-C PAIR
  260.     PUSH    D        SAVE D-E PAIR
  261.     PUSH    H        SAVE H-L PAIR
  262.     MOV    B,A        SAVE CHARACTER IN B
  263.     LDA    IOCON        GET I/O CONFIGURATION
  264.     MOV    C,A        SAVE IN C
  265.     ANI    $40        TEST FOR OUTPUT DISABLED
  266.     JNZ    OEXIT        IF SO, ABORT
  267.     MOV    A,C        GET CONFIGURATION BACK
  268.     ANI    2        TEST FOR VIDEO DISPLAY ENABLED
  269.     JZ    OURT        NO, TRY UART
  270. * OUTPUT TO VIDEO DISPLAY
  271. OVID    LHLD    CURSOR        GET CURSOR POSITION
  272.     LDA    LSTCHR        GET CHARACTER UNDER CURSOR
  273.     MOV    M,A        REPLACE CURSOR
  274.     MOV    A,B        GET CHARACTER TO PRINT
  275.     CPI    13        TEST FOR CR
  276.     JZ    CR        ADVANCE TO NEXT LINE
  277.     CPI    10        TEST FOR LINE-FEED
  278.     JZ    LF        ADVANCE TO NEXT LINE
  279.     CPI    8        TEST FOR BACKSPACE
  280.     JZ    BS        BACK UP
  281.     CPI    14        TEST FOR SHIFT-IN
  282.     JZ    SI        ENABLE EIGHTH BIT
  283.     CPI    15        TEST FOR SHIFT-OUT
  284.     JZ    SO        DISABLE EIGHTH BIT
  285.     CPI    $0C        TEST FOR CLEAR SCREEN
  286.     JZ    CLRSCR        CLEAR THE SCREEN
  287.     CPI    $0B        TEST FOR HOME CHARACTER
  288.     JZ    HOME        HOME THE CURSOR
  289.     MOV    A,C        GET I/O CONFIGURATION
  290.     ANI    $80        ELIMINATE ALL BUT SPECIAL EFFECTS BIT
  291.     ORA    B        OR IN CHARACTER TO BE PRINTED
  292.     MOV    M,A        DISPLAY ON SCREEN
  293.     INX    H        ADVANCE TO NEXT POSITION ON SCREEN
  294.     MOV    A,H        GET HIGH ADDRESS
  295.     CPI    =VIDEO+1024    TEST FOR OFF SCREEN
  296.     JNZ    VEND        IF NOT, WE ARE OK
  297.     CALL    ROLL        SCROLL THE SCREEN
  298.     LXI    H,VIDEO+960    POSITION TO FIRST POSITION OF LAST LINE
  299. VEND    MOV    A,M        GET CHARACTER UNDER CURSOR
  300.     STA    LSTCHR        SAVE IN MEMORY
  301.     MVI    M,$7F        PLACE CURSOR ON SCREEN
  302.     SHLD    CURSOR        SAVE CURSOR POSITION
  303.     JMP    OURT        TEST FOR UART OUTPUT
  304. * DISPLAY CARRIAGE RETURN ON TERMINAL
  305. CR    MOV    A,L        GET LOW SCREEN ADDRESS
  306.     ANI    $C0        BACK UP TO FIRST POS. IN LINE
  307.     MOV    L,A        REPLACE IN ADDRESS
  308.     JMP    VEND        TERMINATE
  309. * LINE-FEED
  310. LF    XCHG            SWAP POSITION TO D-E
  311.     LXI    H,64        ADD 64 TO IT
  312.     DAD    D        GO DOWN ONE LINE
  313.     MOV    A,H        GET HIGH ADDRESS
  314.     CPI    =VIDEO+1024    TEST FOR BEYOND END
  315.     JNZ    VEND        IF NOT, WE ARE OK
  316.     XCHG            GET ADDRESS BACK
  317.     CALL    ROLL        SCROLL SCREEN
  318.     JMP    VEND        TERMINALE
  319. * BACK SPACE
  320. BS    DCX    H        BACK UP POSITION
  321.     MOV    A,H        GET HIGH ADDRESS
  322.     CPI    =VIDEO-1    TEST FOR BEFORE SCREEN
  323.     JNZ    VEND        IF NOT, WE ARE OK
  324.     INX    H        ADVANCE BACK TO VIDEO SCREEN
  325.     JMP    VEND        TERMINATE
  326. * SHIFT OUT, DISABLE EXTRA BIT
  327. SO    MOV    A,C        GET I/O CONFIGURATION
  328.     ANI    $7F        REMOVE EXTRA BIT
  329. SAVIO    STA    IOCON        RESAVE
  330.     JMP    VEND        TERMINATE
  331. * SHIFT IN, ENABLE SPECIAL CHARACTERS
  332. SI    MOV    A,C        GET I/O CONFIG
  333.     ORI    $80        ENABLE EXTRA BIT
  334.     JMP    SAVIO        SAVE AND TERMINATE
  335. * ROLLS SCREEN
  336. ROLL    PUSH    H        SAVE H-L
  337.     LXI    H,VIDEO        GET VIDEO ADDRESS
  338.     LXI    D,VIDEO+64    SECOND LINE ON SCREEN
  339. RLP1    LDAX    D        GET CHARACTER FROM LINE
  340.     MOV    M,A        STORE ONE LINE BACK
  341.     INX    H        ADVANCE POSITION
  342.     INX    D        ADVANCE POSITION
  343.     MOV    A,D        GET ADDRESS
  344.     CPI    =VIDEO+1024    TEST FOR END OF SCREEN
  345.     JNZ    RLP1        IF NOT, KEEP GOING
  346. * CLEAR LAST LINE
  347. RLP2    MVI    M,' '        CLEAR ONE CHARACTER
  348.     INX    H        POINT TO CHARACTER
  349.     CMP    H        TEST FOR END OF SCREEN
  350.     JNZ    RLP2        IF NOT, KEEP GOING
  351.     POP    H        RESTORE H-L
  352.     RET
  353. * CLEAR SCREEN
  354. CLRSCR    MVI    A,=VIDEO+1024    ADDRESS OF END OF SCREEN
  355.     LXI    H,VIDEO        STARTING ADDRESS
  356. CLR1    MVI    M,' '        CLEAR ONE CHARACTER
  357.     INX    H        POINT TO NEXT CHARACTER
  358.     CMP    H        TEST FOR OVER END
  359.     JNZ    CLR1        IF NOT, KEEP GOING
  360. * HOME CURSOR
  361. HOME    LXI    H,VIDEO        SET CURSOR ADDRESS TO TOP LEFT HAND
  362.     JMP    VEND        TERMINATE
  363. * TEST FOR UART OUTPUT
  364. OURT    MOV    A,C        GET I/O CONFIGURATION
  365.     ANI    4        TEST FOR UART ENABLED
  366.     JZ    OUSR        IF NOT, TRY USER SUPPLIED ROUTINE
  367. ULP1    IN    UCTL        GET UART STATUS
  368.     RRC            TEST FOR XMIT READY
  369.     JNC    ULP1        IF NOT, KEEP TRYING
  370.     MOV    A,B        GET CHARACTER
  371.     OUT    UDAT        OUTPUT TO UART
  372. * USER SUPLIED OUTPUT DEVICE
  373. OUSR    MOV    A,C        GET I/O CONFIGURATION
  374.     ANI    $08        TEST FOR USER DEVICE ENABLED
  375.     JZ    OEXIT        IF NOT, EXIT
  376.     LXI    H,OEXIT        ADDRESS TO RETURN TO
  377.     PUSH    H        SAVE ON STACK
  378.     LHLD    USROUT        ADDRESS TO JUMP TO
  379.     PCHL            CALL HIS ROUTINE
  380. OEXIT    POP    H        RESTORE H-L
  381.     POP    D        RESTORE D-E
  382.     MOV    A,B        CHARACTER IS IN A
  383.     POP    B        RESTORE B-C
  384.     RET
  385. *
  386. * INPUT ROUTINE, INPUTS FROM SELECTED DEVICE
  387. *
  388. IN    PUSH    B        SAVE B-C PAIR
  389. INS1    LDA    IOCON        GET INPUT/OUTPUT CONFIGURATION
  390.     MOV    B,A        SAVE COPY IN B FOR FAST REFERENCE
  391.     RRC            TEST FOR INPUT FROM KEYBOARD
  392.     JC    KBD        IF SO, GET CHARACTER FROM KBD
  393. * READ FROM UART
  394. UIN    IN    UCTL        GET UART STATUS
  395.     ANI    2        TEST FOR RECEIVED CHARACTER
  396.     JZ    UIN        IF NOT, WAIT FOR IT
  397.     IN    UDAT        GET DATA FROM UART
  398.     JMP    INEND        PROCESS
  399. * READ FROM KEYBOARD
  400. KBD    IN    KEYBRD        GET KEYBOARD DATA
  401.     RLC            TEST FOR KEY ALREADY PRESSED
  402.     JC    KBD        IF SO, WAIT FOR RELEASE
  403. KBD1    IN    KEYBRD        GET KEYBOARD DATA
  404.     XRI    $80        TEST FOR AND REMOVE STROBE
  405.     JM    KBD1        IF NOT, WAIT FOR A KEY
  406. * PROCESS CHARACTER JUST READ, ACCORDING TO DEFAULTS
  407. INEND    MOV    C,A        SAVE CHARACTER
  408.     CPI    3        TEST FOR CONTROL-C
  409.     MOV    A,B        GET IO CONFIGURATION
  410.     JZ    CTLC        IF CTRL-C, SPECIAL CASE
  411.     ANI    $10        TEST FOR UPPER CASE CONVERSIN
  412.     MOV    A,C        GET CHARACTER BACK
  413.     POP    B        RESTORE B-C PAIR
  414.     RNZ            IF UPPER CASE DISABLED, THEN DON'T CHANGE
  415.     CPI    $61        TEST FOR < LOWER CASE 'A'
  416.     RC            IF SO,  THEN DON'T CHANGE
  417.     CPI    $7B        TEST FOR > LOWER CASE 'Z'
  418.     RNC            IF SO, DON'T CHANGE
  419.     ANI    $5F        CONVERT TO UPPER CASE
  420.     RET
  421. * CONTROL-C, DON'T PASS ON IF CTRL-C IS DISABLED
  422. CTLC    ANI    $20        TEST FOR CONTROL-C DISABLED
  423.     JNZ    INS1        IF SO, GET NEXT CHARACTER
  424.     MOV    A,C        GET CHARACTER BACK
  425.     POP    B        RESTORE B-C
  426.     RET
  427. *
  428. * TEST FOR CTRL-C FROM KEYBOARD. ALSO, IF LINE-FEED IS PRESSED,
  429. * THEN WAIT TILL IT IS RELEASED
  430. *
  431. CTRLC    IN    KEYBRD        GET KEYBOARD DATA
  432.     XRI    $80        TEST AND REMOVE STROBE
  433.     RM            IF NO KEY, QUIT
  434.     CPI    $0A        TEST FOR LINE-FEED
  435.     JZ    CTRLC        IF SO, WAIT TILL RELEASED
  436.     CPI    3        TEST FOR CONTROL-C
  437.     RNZ            IF NOT, DON'T PROCESS
  438.     LDA    IOCON        GET I/O CONFIGURATION
  439.     ANI    $20        TEST FOR CONTROL-C INHIBIT. (Z=0 IF NOT)
  440.     RET
  441. * SET UART COMMAND
  442. UART    CALL    AGET        GET 16 BIT VALUE
  443. *
  444. * INITIALIZES 8251 USART TO VALUE PASSED IN H-L
  445. *
  446. SETURT    MVI    A,3        VALUE TO RESET UART
  447.     OUT    UCTL        MAKE SURE.
  448.     OUT    UCTL        UART IS RESET
  449.     MVI    A,$77        VALUE TO ENTER COMMAND MODE
  450.     OUT    UCTL        ENTER COMMAND MODE
  451.     MOV    A,H        GET HIGH BYTE OF NEW COMMAND WORD
  452.     OUT    UCTL        WRITE TO CONTROL PORT
  453.     MOV    A,L        GET LOW BYTE OF NEW COMMAND WORD
  454.     OUT    UCTL        WRITE TO CONTROL PORT
  455.     RET
  456. * GET'S A 16 BIT VALUE FOR H-L, CY=1 IF EVERYTHING OK
  457. GETHL    CALL    GETBYT        GET FIRST BYTE
  458.     RNC            IF BAD, DON'T WAIT FOR SECOND
  459.     MOV    H,A        SAVE IN HIGH BYTE OF RESULT
  460.     CALL    GETBYT        GET SECOND BYTE
  461.     MOV    L,A        SAVE IN LOW BYTE OF RESULT
  462.     RET
  463. * GETS A BYTE FOR ACC FROM TERMINAL, CY=0 IF FAILS
  464. GETBYT    PUSH    B        SAVE B-C PAIR
  465.     CALL    GETNIB        GEET FIRST NIBBLE
  466.     JNC    RETGB        IF BAD, DON'T WAIT FOR MORE
  467.     RLC            SHIFT INTO.
  468.     RLC            UPPER NIBBLE.
  469.     RLC            OF RESULT.
  470.     RLC            SO WE CAN INSERT LOWER NIBBLE
  471.     MOV    B,A        KEEP HIGH DIGIT IN B
  472.     CALL    GETNIB        GET SECOND DIGIT
  473.     JNC    RETGB        IF BAD, INDICATE SO
  474.     ORA    B        INSERT HIGH DIGIT
  475.     STC            INDICATE SUCESS
  476. RETGB    POP    B        RESTORE B-C PAIR
  477.     RET
  478. * GETS A NIBBLE FROM THE TERMINAL (IN ASCII HEX)
  479. GETNIB    CALL    IN        GET A CHARACTER
  480.     CPI    ' '        TEST FOR BLANK (ABORT1)
  481.     RZ            IF SO, RETURN INDICATING BAD (CY=0)
  482.     CPI    $0D        TEST FOR <CR> (ABORT2)
  483.     RZ            IF SO, RETURN INDICATING BAD
  484.     CPI    '0'        TEST FOR INVALID (BELOW '0')
  485.     JC    GETNIB        IF SO, WAIT FOR MORE
  486.     CPI    'G'        TEST FOR INVALID (GREATER THAN 'F')
  487.     JNC    GETNIB        IF SO, IGNORE
  488.     CALL    OUT        DISPLAY CHARACTER
  489.     CPI    $3A        TEST FOR INVALID
  490.     JC    NUMH        IF OK, WE ARE IN
  491.     CPI    'A'        TEST FOR INVALID
  492.     JC    GETNIB        IF BAD, IGNORE
  493.     SUI    7        CONVERT TO DIGIT
  494. NUMH    SUI    $30        CONVERT TO BINARY
  495.     STC            INDICATE SUCESS
  496.     RET
  497. * LOADS A RECORD IN INTEL HEX FORMAT
  498. GETR    MVI    A,$42        INHIBIT OUTPUT, ENABLE UART
  499.     STA    IOCON        SET I/O CONF
  500.     MVI    A,' '        CLEAR VIDEO FLAG
  501.     STA    VIDEO+63    SO WE CAN FLASH A STAR
  502. GET1    CALL    IN        GET CHARACTER FROM TAPE
  503.     CPI    ':'        TEST FOR START OF RECORD
  504.     JNZ    GET1        IF NOT, IGNORE
  505.     LDA    VIDEO+63    GET VIDEO SCREEN CONTENTS
  506.     XRI    $0A        CONVERT TO/FROM A STAR
  507.     STA    VIDEO+63    RESAVE VIDEO CONTENTS
  508.     CALL    GETBYT        GET LENGTH
  509.     ANA    A        TEST FOR END OF FILE
  510.     JZ    RSET        IF SO, PROCESS
  511.     MOV    C,A        START CHECKSUM
  512.     MOV    B,A        REMEBMER LENGTH
  513.     CALL    GETHL        GET ADDRESS
  514.     MOV    A,C        GET CHECKSUM
  515.     ADD    H        ADD HIGH BYTE OF ADDRESS
  516.     ADD    L        ADD LOW BYTE OF ADDRESS
  517.     MOV    C,A        RESAVE CHECKSUM
  518.     CALL    GETBYT        GET TYPE BYTE
  519.     ADD    C        ADD TO CHECKSUM
  520.     MOV    C,A        RESAVE CHECKSUM
  521. NEOR    CALL    GETBYT        GET DATA BYTE
  522.     MOV    M,A        SAVE IN MEMORY
  523.     INX    H        POINT TO NEXT LOCATION
  524.     ADD    C        ADD TO CHECKSUM
  525.     MOV    C,A        RESAVE CHECKSUM
  526.     DCR    B        REDUCE COUNT OF REMAINING DATA BYTES
  527.     JNZ    NEOR        IF MORE, KEEP LOADING
  528.     CALL    GETBYT        GET CHECKSUM. (FROM TAPE)
  529.     ADD    C        ADD TO COMPUTED CHECKSUM
  530.     JZ    EIPL        IF OK, END THIS RECORD
  531.     CALL    RSET        CLEAR FLAGS
  532.     LXI    H,ERRMSG    ADDRESS OF '?I/O ERROR' MESSAGE
  533.     CALL    PMSG        PRINT MESSAGE
  534.     ANA    A        INDICATE END OF LOAD
  535.     RET
  536. * INDICATE END OF RECORD, MORE DATA TO FOLLOW (CY=1)
  537. EIPL    CALL    RSET        RESET DEFAULT I/0
  538.     STC            INDICATE MORE DATA
  539.     RET
  540. * RESET I/O CONFIGURATION
  541. RSET    MVI    A,DEFIO        SET TO DEFAULT I/O
  542.     STA    IOCON        SAVE IN I/O CONF
  543.     ANA    A        INDICATE DONE
  544.     RET
  545. ERRMSG    STR    '?I/O ERROR'    ERROR MESSAGE
  546.     DB    $0D
  547. * DISPLAYS MESSAGE ON DISPLAY UP TO A CARRIAGE-RETURN. OR ZERO
  548. PMSG    MOV    A,M        GET CHARACTER FROM MESSAGE
  549.     ANA    A        END OF MESSAGE?
  550.     RZ            IF SO, RETURN
  551.     CALL    OUT        DISPLAY IT
  552.     INX    H        POINT TO NEXT CHAR. IN MESSAGE
  553.     CPI    $0D        TEST FOR CARRIAGE RETURN
  554.     JNZ    PMSG        IF NOT, KEEP DISPLAYING
  555. * DISPLAYS A LINE-FEED, CARRIAGE-RETURN PAIR ON THE VIDEO DISPLAY
  556. NL    MVI    A,$0A        GET LINE-FEED
  557.     CALL    OUT        DISPLAY
  558.     MVI    A,$0D        GET CARRIAGE RETURN
  559.     JMP    OUT        DISPLAY AND RETURN
  560. * LOAD COMMAND
  561. LOAD    CALL    TON        TURN TAPE ON
  562. * DOWNLOAD COMMAND
  563. DNLD    MVI    D,$FF        SET NUMBER OF RECORDS DUMPED TO 255
  564.     CALL    NL        ADVANCE TO A NEW LINE
  565. LODLP    INR    D        ADVANCE NUMBER OF RECORDS DUMPED
  566.     MOV    A,D        GET NUMBER OF RECORDS DUMPED
  567.     CALL    HOUT        DISPLAY ON TERMINAL
  568.     CALL    GETR        GET NEXT RECORD
  569.     RNC            IF END, GET NEXT COMMAND
  570.     MVI    A,$0D        GET CARRIAGE RETURN
  571.     CALL    OUT        BACK UP TO START OF LINE
  572.     JMP    LODLP        GET NEXT RECORD
  573. * POSITIONS CURSOR TO POSITION PASSED IN H-L
  574. CURPOS    PUSH    D        SAVE D-E
  575.     XCHG            SWAP TO D-E
  576.     LHLD    CURSOR        GET OLD CURSOR POSITION
  577.     LDA    LSTCHR        GET LAST CHARACTER
  578.     MOV    M,A        REPLACE IN SCREEN MEMORY
  579.     LXI    H,VIDEO        START OF VIDEO DISPLAY
  580.     DAD    D        OFFSET INTO DISPLAY
  581.     MOV    A,M        GET CHARACTER UNDER NEW CURSOR
  582.     STA    LSTCHR        SAVE IN MEMORY
  583.     MVI    M,$7F        PUT CURSOR ON SCREEN
  584.     SHLD    CURSOR        RESAVE CURSOR POSITION
  585.     POP    D        RESTORE D-E
  586.     RET
  587. * START TAPE DRIVE, AND WAIT
  588. TON    MVI    A,$35        SET FOR TAPE ON
  589.     OUT    UCTL        WRITE TO UART CONTROL
  590. * DELAY, WAITS A FINITE TIME INTERVAL
  591. DELAY    PUSH    H        SAVE H-L
  592.     LXI    H,0        START COUNTING FROM ZERO
  593. DEL1    DCX    H        REDUCE COUNT
  594.     MOV    A,H        GET HIGH VALUE
  595.     ORA    L        TEST FOR ZERO WITH LOW VALUE
  596.     JNZ    DEL1        IF NOT, KEEP COUNTING
  597.     POP    H        RESTORE H-L
  598.     RET
  599. * SHUT'S OFF TAPE DRIVE
  600. TOFF    IN    UCTL        GET UART DATA
  601.     RRC            WAIT FOR XMIT READY
  602.     JNC    TOFF        TO WE DON'T CLOBBER LAST CHAR SENT
  603.     MVI    A,' '        GET A BLANK
  604.     STA    VIDEO+63    INSURE DISPLAYED '*' IS OFF
  605.     MVI    A,$37        SHUT OFF TAPE DRIVE
  606.     OUT    UCTL        TURN IT OFF
  607.     RET
  608. *
  609. * TERMINAL MODE.... SIMULATES A DUMB ASCII TERMNAL
  610. *
  611. TMODE    CALL    IN        GET DATA CHARACTER
  612.     MOV    B,A        SAVE IN B FOR LATER REF
  613. * READ/WRITE TERMINAL AND UART
  614. TWAIT    CALL    CRCVR        TEST UART RECEIVER
  615.     IN    KEYBRD        GET KEYBOARD DATA
  616.     RLC            TEST FOR KEY PRESSED
  617.     JC    TWAIT        IF SO, WAIT TILL RELEASED
  618. KEYIN    CALL    CRCVR        TEST FOR UART DATA RECEIVED
  619.     IN    KEYBRD        GET KEYBOARD DATA
  620.     XRI    $80        TEST AND REMOVE STROBE
  621.     JM    KEYIN        IF NO DATA, WAIT FOR SOME
  622.     RZ            IF NULL (CTRL-@) RETURN TO MONITOR
  623.     OUT    UDAT        WRITE TO UART DATA PORT
  624.     MOV    C,A        SAVE FOR REFERENCE
  625.     MOV    A,B        GET DUPLEX INDICATOR
  626.     CPI    'H'        TEST FOR HALF DUPLEX
  627.     MOV    A,C        GET CHARACTER BACK
  628.     CZ    PCHRS        IF HALD DUP, DISPLAY CHAR
  629.     JMP    TWAIT        WAIT FOR KEY RELEASE
  630. * TEST UART AND DISPLAY AND DATA RECEIVED
  631. CRCVR    IN    UCTL        GET UART STATUS
  632.     ANI    2        TEST FOR RX READY
  633.     RZ            IF NOT, FORGET IT
  634.     IN    UDAT        GET UART DATA
  635. PCHRS    CPI    $0D        TEST FOR CARRIAGE RETURN
  636.     JZ    OUT        OK TO DISPLAY
  637.     CPI    $0A        TEST FOR LINE-FEED
  638.     JZ    OUT        OK TO DISPLAY
  639.     CPI    $08        TEST FOR BACK-SPACE
  640.     JZ    OUT        OK TO DISPLAY
  641.     CPI    $7F        TEST FOR DELETE CHARACTER
  642.     RZ            NOT OK TO DISPLAY
  643.     CPI    ' '        TEST FOR CONTROL CHARACTERS
  644.     JNC    OUT        ONLY DISPLAY DISPLAYABLE CHARACTERS
  645.     RET
  646.